home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvi2tty / disdvi.c < prev    next >
C/C++ Source or Header  |  1995-01-12  |  15KB  |  473 lines

  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /*   disdvi  ---  disassembles TeX dvi files.                                */
  4. /*                                                                           */
  5. /*                                                                           */
  6. /*    2.0 23/01/89 M.J.E. Mol (c) 1989              marcel@duteca.tudelft.nl */
  7. /*    2.1 19/01/90 M.J.E. Mol    Maintain a list of fonts and                */
  8. /*                               show fontnames in font changes.             */
  9. /*                               Show character code when printing ligatures */
  10. /*                                                                           */
  11. /*                                                                           */
  12. /*****************************************************************************/
  13.  
  14.  
  15. char *disdvi = "@(#) disdvi.c  2.1 19/01/90 M.J.E. Mol (c) 1989, 1990";
  16.  
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include "commands.h"
  20. #if defined(MSDOS)
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <fcntl.h>
  24. #endif
  25.  
  26. #define LASTCHAR        127    /* max dvi character, above are commands    */
  27.  
  28. #define get1()           num(1)
  29. #define get2()           num(2)
  30. #define get3()           num(3)
  31. #define get4()           num(4)
  32. #define sget1()         snum(1)
  33. #define sget2()         snum(2)
  34. #define sget3()         snum(3)
  35. #define sget4()         snum(4)
  36.  
  37. typedef struct _font {
  38.     long    num;
  39.     struct _font * next;
  40.     char  * name;
  41. } font;
  42.  
  43. font * fonts = NULL;
  44. FILE * dvifp;
  45. char * dvi_name;
  46. long   pc = 0;
  47.  
  48. char *          malloc          ();
  49.  
  50. void            main            ();
  51. void            bop             ();
  52. void            preamble        ();
  53. void            postamble       ();
  54. void            postpostamble   ();
  55. void            fontdef         ();
  56. char *          fontname        ();
  57. void            special         ();
  58. void            printnonprint   ();
  59. unsigned long   num             ();
  60. long            snum            ();
  61.  
  62.  
  63.  
  64.  
  65. /*---------------------------------------------------------------------------*/
  66.  
  67. void main(argc, argv)
  68. int argc;
  69. char **argv;
  70. {
  71.     register int opcode;                /* dvi opcode                        */
  72.     register int i;
  73.     int fontnum;
  74.  
  75.     if (argc > 2) {
  76.         fprintf(stderr, "To many arguments\n");
  77.         fprintf(stderr, "Usage: %s [dvi-file]\n", *argv);
  78.         exit(1);
  79.     }
  80.  
  81.     if (argc == 2) {
  82.         if ((i = strlen(argv[1])) == 0) {
  83.             fprintf(stderr, "Illegal empty filename\n");
  84.             fprintf(stderr, "Usage: %s [dvi-file]\n", *argv);
  85.             exit(2);
  86.         }
  87.         if ((i >= 5) && (argv[1][i-4] == '.') && (argv[1][i-3] == 'd') &&
  88.               (argv[1][i-2] == 'v') && (argv[1][i-1] == 'i'))
  89.             dvi_name = argv[1];
  90.         else {
  91.             dvi_name = malloc((i+5) * sizeof(char));
  92.             strcpy(dvi_name, argv[1]);
  93.             strcat(dvi_name, ".dvi");
  94.         }
  95.         if ((dvifp = fopen(dvi_name, "r")) == NULL) {
  96.             perror(dvi_name);
  97.             exit(3);
  98.         }
  99.     }
  100.     else
  101.         dvifp = stdin;
  102.  
  103. #if defined(MSDOS)
  104.     setmode(fileno(dvifp), O_BINARY);
  105. #endif
  106.  
  107.     while ((opcode = (int) get1()) != EOF) {    /* process until end of file */
  108.         printf("%06ld: ", pc - 1);
  109.         if ((opcode <= LASTCHAR) && isprint(opcode)) {
  110.             printf("Char:     ");
  111.             while ((opcode <= LASTCHAR) && isprint(opcode)) {
  112.                 putchar(opcode);
  113.                 opcode = (int) get1();
  114.             }
  115.             putchar('\n');
  116.             printf("%06ld: ", pc - 1);
  117.         }
  118.  
  119.         if (opcode <= LASTCHAR) 
  120.             printnonprint(opcode);              /* it must be a non-printable */
  121.         else if ((opcode >= FONT_00) && (opcode <= FONT_63)) 
  122.             printf("FONT_%02d              /* %s */\n", opcode - FONT_00,
  123.                                     fontname(opcode - FONT_00));
  124.         else
  125.             switch (opcode) {
  126.                 case SET1     :
  127.                 case SET2     : 
  128.                 case SET3     :
  129.                 case SET4     : printf("SET%d:    %ld\n", opcode - SET1 + 1,
  130.                                                        num(opcode - SET1 + 1));
  131.                                 break;
  132.                 case SET_RULE : printf("SET_RULE: height: %ld\n", sget4());
  133.                                 printf("%06ld: ", pc);
  134.                                 printf("          length: %ld\n", sget4());
  135.                                 break;
  136.                 case PUT1     :
  137.                 case PUT2     :
  138.                 case PUT3     :
  139.                 case PUT4     : printf("PUT%d:     %ld\n", opcode - PUT1 + 1,
  140.                                                        num(opcode - PUT1 + 1));
  141.                                 break;
  142.                 case PUT_RULE : printf("PUT_RULE: height: %ld\n", sget4());
  143.                                 printf("%06ld: ", pc);
  144.                                 printf("          length: %ld\n", sget4());
  145.                                 break;
  146.                 case NOP      : printf("NOP\n");  break;
  147.                 case BOP      : bop();            break;
  148.                 case EOP      : printf("EOP\n");  break;
  149.                 case PUSH     : printf("PUSH\n"); break;
  150.                 case POP      : printf("POP\n");  break;
  151.                 case RIGHT1   :
  152.                 case RIGHT2   : 
  153.                 case RIGHT3   : 
  154.                 case RIGHT4   : printf("RIGHT%d:   %ld\n", opcode - RIGHT1 + 1,
  155.                                                      snum(opcode - RIGHT1 + 1));
  156.                                 break;
  157.                 case W0       : printf("W0\n");   break;
  158.                 case W1       : 
  159.                 case W2       :
  160.                 case W3       :
  161.                 case W4       : printf("W%d:       %ld\n", opcode - W0,
  162.                                                       snum(opcode - W0));
  163.                                 break;
  164.                 case X0       : printf("X0\n");   break;
  165.                 case X1       :
  166.                 case X2       :
  167.                 case X3       :
  168.                 case X4       : printf("X%d:       %ld\n", opcode - X0,
  169.                                                       snum(opcode - X0));
  170.                                 break;
  171.                 case DOWN1    : 
  172.                 case DOWN2    : 
  173.                 case DOWN3    :
  174.                 case DOWN4    : printf("DOWN%d:    %ld\n", opcode - DOWN1 + 1,
  175.                                                       snum(opcode - DOWN1 + 1));
  176.                                 break;
  177.                 case Y0       : printf("Y0\n");   break;
  178.                 case Y1       :
  179.                 case Y2       :
  180.                 case Y3       :
  181.                 case Y4       : printf("Y%d:       %ld\n", opcode - Y0,
  182.                                                       snum(opcode - Y0));
  183.                                 break;
  184.                 case Z0       : printf("Z0\n");   break;
  185.                 case Z1       :
  186.                 case Z2       :
  187.                 case Z3       : 
  188.                 case Z4       : printf("Z%d:       %ld\n", opcode - Z0,
  189.                                                       snum(opcode - Z0));
  190.                                 break;
  191.                 case FNT1     :
  192.                 case FNT2     :
  193.                 case FNT3     :
  194.                 case FNT4     : fontnum = num(opcode -FNT1 + 1);
  195.                                 printf("FNT%d:     %ld    /* %s */\n",
  196.                                        opcode - FNT1 + 1, fontnum,
  197.                                        fontname(fontnum));
  198.                                 break;
  199.                 case XXX1     : 
  200.                 case XXX2     : 
  201.                 case XXX3     :
  202.                 case XXX4     : special(opcode - XXX1 + 1);     break;
  203.                 case FNT_DEF1 :
  204.                 case FNT_DEF2 :
  205.                 case FNT_DEF3 :
  206.                 case FNT_DEF4 : fontdef(opcode - FNT_DEF1 + 1); break;
  207.                 case PRE      : preamble();                     break;
  208.                 case POST     : postamble();                    break;
  209.                 case POST_POST: postpostamble();                break;
  210.             }
  211.     }
  212.  
  213. } /* main */
  214.  
  215.  
  216. /*----------------------------------------------------------------------------*/
  217.  
  218.  
  219. void bop()
  220. {
  221.     int i;
  222.  
  223.     printf("BOP       page number      : %ld", sget4());
  224.     for (i=0; i < 9; i++) {
  225.         if (i % 3 == 0)
  226.             printf("\n%06ld:         ", pc);
  227.         printf("  %6ld", sget4()); 
  228.     }
  229.     printf("\n%06ld: ", pc);
  230.     printf("          prev page offset : %06ld\n", sget4()); 
  231.  
  232. } /* bop */
  233.  
  234.  
  235. /*---------------------------------------------------------------------------*/
  236.  
  237. void postamble() 
  238. {
  239.  
  240.     printf("POST      last page offset : %06ld\n", sget4());
  241.     printf("%06ld: ", pc);
  242.     printf("          numerator        : %ld\n", get4());
  243.     printf("%06ld: ", pc);
  244.     printf("          denominator      : %ld\n", get4());
  245.     printf("%06ld: ", pc);
  246.     printf("          magnification    : %ld\n", get4());
  247.     printf("%06ld: ", pc);
  248.     printf("          max page height  : %ld\n", get4());
  249.     printf("%06ld: ", pc);
  250.     printf("          max page width   : %ld\n", get4());
  251.     printf("%06ld: ", pc);
  252.     printf("          stack size needed: %d\n", (int) get2());
  253.     printf("%06ld: ", pc);
  254.     printf("          number of pages  : %d\n", (int) get2());
  255.  
  256. } /* postamble */
  257.  
  258. void preamble()
  259. {
  260.     register int i;
  261.  
  262.     printf("PRE       version          : %d\n", (int) get1());
  263.     printf("%06ld: ", pc);
  264.     printf("          numerator        : %ld\n", get4());
  265.     printf("%06ld: ", pc);
  266.     printf("          denominator      : %ld\n", get4());
  267.     printf("%06ld: ", pc);
  268.     printf("          magnification    : %ld\n", get4());
  269.     printf("%06ld: ", pc);
  270.     i = (int) get1();
  271.     printf("          job name (%3d)   :", i);
  272.     while (i-- > 0)
  273.         putchar((int) get1());
  274.     putchar('\n');
  275.  
  276. } /* preamble */
  277.  
  278.  
  279. void postpostamble()
  280. {
  281.     register int i;
  282.  
  283.     printf("POSTPOST  postamble offset : %06ld\n", get4());
  284.     printf("%06ld: ", pc);
  285.     printf("          version          : %d\n", (int) get1());
  286.     while ((i = (int) get1()) == TRAILER) {
  287.         printf("%06d: ", pc - 1);
  288.         printf("TRAILER\n");
  289.     }
  290.     while (i != EOF) {
  291.         printf("%06ld: ", pc - 1);
  292.         printf("BAD DVI FILE END: 0x%02X\n", i);
  293.         i = (int) get1();
  294.     }
  295.  
  296. } /* postpostamble */
  297.  
  298.  
  299.  
  300. void special(x)
  301. register int x;
  302. {
  303.     register long len;
  304.     register long i;
  305.  
  306.     len = num(x);
  307.     printf("XXX%d:     %ld bytes\n", x, len);
  308.     printf("%06ld: ", pc);
  309.     for (i = 0; i < len; i++)      /* a bit dangerous ... */
  310.         putchar((int) get1());     /*   can be non-printables */
  311.     putchar('\n');
  312.  
  313. } /* special */
  314.  
  315.  
  316.  
  317. void fontdef(x)
  318. register int x;
  319. {
  320.     register int i;
  321.     char * name;
  322.     font * fnt;
  323.     int namelen;
  324.     long fntnum;
  325.     int new = 0;
  326.  
  327.     fntnum = num(x);
  328.     printf("FNT_DEF%d: %ld\n", x, fntnum);
  329.     printf("%06ld: ", pc);           /* avoid side-effect on pc in get4() */
  330.     printf("          checksum         : %ld\n", get4());
  331.     printf("%06ld: ", pc);
  332.     printf("          scale            : %ld\n", get4());
  333.     printf("%06ld: ", pc);
  334.     printf("          design           : %ld\n", get4());
  335.     printf("%06ld: ", pc);
  336.     printf("          name             : ");
  337.     namelen = (int) get1() + (int) get1();
  338.     fnt = fonts;
  339.     while (fnt != NULL && fnt->num != fntnum)
  340.         fnt = fnt->next;
  341.     if (fnt == NULL) {
  342.         if ((fnt = (font *) malloc(sizeof(font))) == NULL) {
  343.             perror("fontdef");
  344.             exit(1);
  345.         }
  346.         fnt->num = fntnum;
  347.         new = 1;
  348.     }
  349.     else
  350.         free(fnt->name);    /* free old name */
  351.     if ((name = (char *) malloc(namelen * sizeof(char))) == NULL) {
  352.         perror("fontdef");
  353.         exit(1);
  354.     }
  355.     
  356.     for (i = 0; i < namelen; i++)
  357.         name[i] = get1();
  358.     fnt->name = name;
  359.     if (new) {
  360.         fnt->next = fonts;
  361.         fonts = fnt;
  362.     }
  363.  
  364.     printf("%s\n", name);
  365.  
  366. } /* fontdef */
  367.  
  368.  
  369.  
  370. char * fontname(fntnum)
  371. long fntnum;
  372. {
  373.     font * fnt;
  374.  
  375.     fnt = fonts;
  376.     while (fnt != NULL && fnt->num != fntnum)
  377.         fnt = fnt->next;
  378.     if (fnt != NULL)
  379.         return fnt->name;
  380.     else
  381.         return "unknown fontname";
  382.    
  383. } /* fontname */
  384.  
  385.  
  386.  
  387. void printnonprint(ch)
  388. register int ch;
  389. {
  390.  
  391.     printf("Char:     ");
  392.     switch (ch) {
  393.         case 11  :  printf("ff         /* ligature (non-printing) 0x%02X */",
  394.                            ch);
  395.                     break;
  396.         case 12  :  printf("fi         /* ligature (non-printing) 0x%02X */",
  397.                            ch);
  398.                     break;
  399.         case 13  :  printf("fl         /* ligature (non-printing) 0x%02X */",
  400.                            ch);
  401.                     break;
  402.         case 14  :  printf("ffi        /* ligature (non-printing) 0x%02X */",
  403.                            ch);
  404.                     break;
  405.         case 15  :  printf("ffl        /* ligature (non-printing) 0x%02X */",
  406.                            ch);
  407.                     break;
  408.         case 16  :  printf("i          /* (non-printing) 0x%02X */", ch);
  409.                     break;
  410.         case 17  :  printf("j          /* (non-printing) 0x%02X */", ch);
  411.                     break;
  412.         case 25  :  printf("ss         /* german (non-printing) 0x%02X */", ch);
  413.                     break;
  414.         case 26  :  printf("ae         /* scadinavian (non-printing) 0x%02X */",
  415.                            ch);
  416.                     break;
  417.         case 27  :  printf("oe         /* scadinavian (non-printing) 0x%02X */",
  418.                            ch);
  419.                     break;
  420.         case 28  :  printf("o          /* scadinavian (non-printing) 0x%02X */",
  421.                            ch);
  422.                     break;
  423.         case 29  :  printf("AE         /* scadinavian (non-printing) 0x%02X */",
  424.                            ch);
  425.                     break;
  426.         case 30  :  printf("OE         /* scadinavian (non-printing) 0x%02X */",
  427.                            ch);
  428.                     break;
  429.         case 31  :  printf("O          /* scadinavian (non-printing) 0x%02X */",
  430.                            ch);
  431.                     break;
  432.         default  :  printf("0x%02X", ch); break;
  433.     }
  434.     putchar('\n');
  435.  
  436. }
  437.  
  438.  
  439.  
  440. unsigned long num(size)
  441. register int size;
  442. {
  443.     register int i;
  444.     register long x = 0;
  445.  
  446.     pc += size;
  447.     for (i = 0; i < size; i++)
  448.         x = (x << 8) + (unsigned) getc(dvifp);
  449.     return x;
  450.  
  451. } /* num */
  452.  
  453.  
  454.  
  455. long snum(size)
  456. register int size;
  457. {
  458.     register int i;
  459.     register long x = 0;
  460.  
  461.     pc += size;
  462.     x = getc(dvifp);
  463.     if (x & 0x80)
  464.         x -= 0x100;
  465.     for (i = 1; i < size; i++)
  466.         x = (x << 8) + (unsigned) getc(dvifp);
  467.     return x;
  468.  
  469. } /* snum */
  470.  
  471.  
  472.  
  473.